/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.hiof.menus;

import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.Toast;
import com.hiof.Configuration;
import com.hiof.R;
import com.hiof.servercommunication.RestFulServiceManager;
import com.hiof.servercommunication.exception.NetworkException;
import com.hiof.servercommunication.exception.ServerException;
import com.hiof.settings.user.UserConfiguration;
import com.hiof.utility.Utility;
import com.hiof.voiceguide.Speaker;
import com.hiof.voiceguide.VoiceType;

import java.util.ArrayList;

/**
 * @author manish
 */
public class NavigationMenu {
    private int currentState;
    private static NavigationMenu instance;
    private ArrayList<CommandItem> menuItems = new ArrayList<CommandItem>();

    public void addMoreCommand(CommandItem item) {
        menuItems.add(item);
    }

    public static NavigationMenu getInstance() {
        if (instance == null) {
            instance = new NavigationMenu();
        }
        return instance;
    }

    public void destroy() {
        if (instance != null)
            instance = null;
    }

    private NavigationMenu() {
        init();
    }

    public void init() {
        addMoreCommand(new CommandItem(VoiceType.TEXT_TO_SPEECH, R.string.remaining_current_distance));
        addMoreCommand(new CommandItem(VoiceType.TEXT_TO_SPEECH, R.string.support_information));
        reset();
    }

    private void reset() {
        currentState = -1;
    }

    public void next() {
        currentState++;
        if (currentState >= menuItems.size()) {
            currentState = 0;
        }
        speakCurrentState();
    }

    public void previous() {
        currentState--;
        if (currentState < 0) {
            currentState = menuItems.size() - 1;
        }
        speakCurrentState();
    }

    public void select() {
        if (currentState < 0) {
            Speaker.speak(VoiceType.AUDIO_FILE, R.raw.metalhit);
        } else {
            queryServer();
        }
        reset();
    }

    public void cancel() {
        Speaker.speak(VoiceType.TEXT_TO_SPEECH, R.string.cancel);
        reset();
    }

    private void speakCurrentState() {
        CommandItem item = menuItems.get(currentState);
        Speaker.speak(item.getVoiceType(), item.getArtifactId());
    }

    private void queryServer() {
        ServerQuerier q = new ServerQuerier();
        Thread t = new Thread(q);
        t.start();
    }

    class ServerQuerier implements Runnable {
        CommandItem item = menuItems.get(currentState);
        String message = "no response";

        public void run() {
            try {
                if (item.getArtifactId() == R.string.remaining_current_distance) {
                    message = RestFulServiceManager.getInstance().getNextTargetLocation(UserConfiguration.getInstance().getAttendantId()).getMessage();
                    Bundle b = new Bundle();
                    b.putString("message", message);
                    b.putInt("index", -1);
                    Message m = new Message();
                    m.setData(b);
                    commandSuccessHandler.sendMessage(m);
                } else if (item.getArtifactId() == R.string.support_information) {
                    message = RestFulServiceManager.getInstance().getTeamMemberLocationInfoOfSupport(UserConfiguration.getInstance().getAttendantId()).getMessage();
                    Bundle b = new Bundle();
                    b.putString("message", message);
                    b.putInt("index", -1);
                    Message m = new Message();
                    m.setData(b);
                    commandSuccessHandler.sendMessage(m);
                } else if (item.getArtifactId() == R.string.call_support) {
                    Bundle b = new Bundle();
                    b.putInt("index", 0);
                    Message m = new Message();
                    m.setData(b);
                    commandSuccessHandler.sendMessage(m);
                } else if (item.getArtifactId() == R.string.call_first_support) {
                    Bundle b = new Bundle();
                    b.putInt("index", 0);
                    Message m = new Message();
                    m.setData(b);
                    commandSuccessHandler.sendMessage(m);
                } else if (item.getArtifactId() == R.string.call_second_support) {
                    Bundle b = new Bundle();
                    b.putInt("index", 1);
                    Message m = new Message();
                    m.setData(b);
                    commandSuccessHandler.sendMessage(m);
                }
            } catch (NetworkException e) {
                Utility.error(this.getClass().toString(), e.getErrorMessage());
                handleError(e.getErrorMessage());
            } catch (ServerException e) {
                Utility.error(this.getClass().toString(), e.getErrorMessage());
                handleError(e.getErrorMessage());
            }
        }
    }

    private void handleError(String message) {
        Message msg = new Message();
        Bundle bundle = new Bundle();
        bundle.putString("message", message);
        msg.setData(bundle);
        commandExceptionHandler.sendMessage(msg);
    }


    private void processCallCommand(int index) {
        String fullName = UserConfiguration.getInstance().getSupportFullnameByIndex(index);
        String mobilePhone = UserConfiguration.getInstance().getSupportMobilePhoneByIndex(index);
        if("".equals(mobilePhone)){
            Speaker.speak(VoiceType.TEXT_TO_SPEECH, "Invalid phone number.");
            return;
        }
        Speaker.speak(VoiceType.TEXT_TO_SPEECH, "Calling " + fullName + " . Please wait.");
        call(mobilePhone);
    }

    private void call(String phoneNumber) {
        try {
            AudioManager audioManager = (AudioManager) Configuration.getInstance().getCurrentContext().getSystemService(Context.AUDIO_SERVICE);
            audioManager.setSpeakerphoneOn(true);
            Intent callIntent = new Intent(Intent.ACTION_CALL);
            callIntent.setData(Uri.parse("tel:" + phoneNumber));
            Configuration.getInstance().getCurrentContext().startActivity(callIntent);
        } catch (ActivityNotFoundException e) {
            Utility.error(this.getClass().toString(), "Call failed:" + e.getMessage());
        }
    }

    Handler commandSuccessHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg != null && msg.getData() != null) {
                int index = Integer.parseInt(String.valueOf(msg.getData().get("index")));
                if (index == -1)
                    Speaker.speak(VoiceType.TEXT_TO_SPEECH, msg.getData().get("message").toString());
                else
                    processCallCommand(index);
            }
        }
    };

    private Handler commandExceptionHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            Toast.makeText(Configuration.getInstance().getCurrentContext(), String.valueOf(msg.getData().get("message")), Toast.LENGTH_SHORT).show();
            Speaker.speak(VoiceType.TEXT_TO_SPEECH, R.string.no_internet);
        }
    };

}